package com.om.base;
/**   
* @CopyRright (c) 
* @Title:XmlParse.java
* @Description: 提供对Xml文件的操作，以及和AbstractBean之间的相互转化
* @author tangchuan
* @CreateDate 2014-10-14   
* @version V1.0   
*/ 
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;


public class XmlParse {
    private Document xmlDoc = null;
    private Hashtable table = new Hashtable();
    private DataInputStream xmlInput = null;
    private List nodeList = new ArrayList();
    private String beanname = "";
    private AbstractBean bean = null;
    private ArrayList<AbstractBean> beanList = new ArrayList();
    private HashMap<String, String> name_valueMap = new HashMap();
    private int isNew = 0;
    private String spit = "";

    public XmlParse(File file, AbstractBean bean) {
        try {
            FileInputStream fIn = new FileInputStream(file);
            this.bean = bean;
            this.spit = bean.TABLE_NAME;

            this.beanname = bean.getClassName();
            this.xmlInput = new DataInputStream(fIn);
            parseXml();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public XmlParse(String xml, AbstractBean bean, String spit) {
        this.bean = bean;
        this.beanname = bean.getClassName();
        this.spit = spit;

        try {
            this.xmlInput = (this.xmlInput = new DataInputStream(new ByteArrayInputStream(xml.getBytes("utf8"))));
            parseXml();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public XmlParse(InputStream in, AbstractBean bean) {
        this.bean = bean;
        this.spit = bean.TABLE_NAME;
        this.beanname = bean.getClassName();
        this.xmlInput = new DataInputStream(in);
        parseXml();
    }

    public XmlParse(InputStream in) {
        this.xmlInput = new DataInputStream(in);
        parseXml();
    }

    public XmlParse(String xml) {
        try {
            this.xmlInput = (this.xmlInput = new DataInputStream(new ByteArrayInputStream(
                            xml.getBytes("utf8"))));
            parseXml();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public XmlParse(File file) {
        int size = 0;

        try {
            FileInputStream fIn = new FileInputStream(file);

            for (; fIn.read() != 0; ++size)
                ;

            this.xmlInput = new DataInputStream(fIn);

            byte[] bt = new byte[size];
            String xml = new String(bt, "utf8");
            this.xmlInput = (this.xmlInput = new DataInputStream(new ByteArrayInputStream(
                            xml.getBytes())));
            parseXml();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List getListByName(String name) {
        List list = new ArrayList();

        if (this.table.containsKey(name)) {
            list = (List) this.table.get(name);
        }

        return list;
    }

    public ArrayList<AbstractBean> getBeanList() {
        return this.beanList;
    }

    public HashMap getName_ValueMap() {
        return this.name_valueMap;
    }

    public HashMap getMapbyName(String name) {
        NamedNodeMap attrMap = null;
        HashMap map = new HashMap();

        Node element = this.xmlDoc.getElementsByTagName(name).item(0);

        if (element == null) {
            return map;
        }

        if (!(element.hasAttributes())) {
            return map;
        }

        attrMap = element.getAttributes();

        for (int i = 0; i < attrMap.getLength(); ++i) {
            if (attrMap.item(i).getNodeName().trim().equals("id")) {
                continue;
            }

            map.put(attrMap.item(i).getNodeName(),
                attrMap.item(i).getNodeValue());
        }

        return map;
    }

    public List getNodeList() {
        List list = new ArrayList();
        list = this.nodeList;

        return list;
    }

    Hashtable getListTable() {
        return this.table;
    }

    public void printElement() {
        Iterator keys = this.name_valueMap.keySet().iterator();

        while (keys.hasNext()) {
            String key = (String) keys.next();
            System.out.println(key + " = " +
                ((String) this.name_valueMap.get(key)));
        }
    }

    private void parseXml() {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            this.xmlDoc = builder.parse(this.xmlInput);
            doParse(this.xmlDoc.getDocumentElement());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void doParse(Node node) {
        if (node.getNodeName().equals(this.spit)) {
            this.isNew = 1;
        }

        if (node.getNodeType() == 3) {
            putElement(node);
        }

        for (int i = 0; i < node.getChildNodes().getLength(); ++i) {
            doParse(node.getChildNodes().item(i));
        }

        if (!(node.hasAttributes())) {
            return;
        }

        loadBean(node.getAttributes());

        for (int i = 0; i < node.getAttributes().getLength(); ++i) {
            doParse(node.getAttributes().item(i));
        }
    }

    private void putElement(Node node) {
        if (node.getNodeValue().trim().length() <= 0) {
            return;
        }

        String name = node.getParentNode().getNodeName();
        List list = new ArrayList();

        if ((!(this.beanname.equals(""))) &&
                (this.bean.getFieldIndex(name) == -1)) {
            return;
        }

        if (this.table.containsKey(name)) {
            list = (List) this.table.get(name);
        }

        list.add(node.getNodeValue());
        this.table.put(name, list);
        this.name_valueMap.put(name, node.getNodeValue());

        if (this.bean == null) {
            return;
        }

        loadBean(node);
    }

    private void loadBean(NamedNodeMap map) {
        if (this.beanname.equals("")) {
            return;
        }

        AbstractBean bean = null;

        try {
            bean = BeanFactory.LoadBean(this.beanname);

            for (int i = 0; i < map.getLength(); ++i) {
                Node node = map.item(i);
                bean.set(node.getNodeName(), node.getNodeValue());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        this.beanList.add(bean);
    }

    private void loadBean(Node node) {
        try {
            Node parent = node.getParentNode();
            Node grand = parent.getParentNode();

            if ((parent == null) || (grand == null)) {
                return;
            }

            AbstractBean bean =null;

            if (this.isNew == 1) {
                bean = BeanFactory.LoadBean(this.beanname);
                this.beanList.add(bean);
                this.isNew = 0;
            } else if (this.beanList.size() > 0) {
                bean = (AbstractBean) this.beanList.get(this.beanList.size() -
                        1);
            }

            bean.set(node.getParentNode().getNodeName().trim(),
                node.getNodeValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

